-- ============================================================================
-- 智能开关 Lua 插件示例
-- 协议：SmartSwitch-V1.0
-- 功能：开关控制、状态上报、用电统计
-- ============================================================================

protocol_name = "SmartSwitch-V1"

-- ============================================================================
-- 辅助函数
-- ============================================================================

-- 计算校验和（简单累加）
local function calcChecksum(data, start_pos, end_pos)
    local sum = 0
    for i = start_pos, end_pos do
        sum = sum + data[i]
    end
    return sum % 256
end

-- 验证数据包
local function validatePacket(data, dataLen)
    -- 最小长度检查
    if dataLen < 6 then
        return false, "数据长度不足"
    end
    
    -- 帧头检查
    if data[1] ~= 0xAA or data[2] ~= 0x55 then
        return false, "帧头错误"
    end
    
    -- 帧尾检查
    if data[dataLen] ~= 0x16 then
        return false, "帧尾错误"
    end
    
    -- 校验和检查
    local checksum = data[dataLen - 1]
    local calculated = calcChecksum(data, 3, dataLen - 2)
    if checksum ~= calculated then
        return false, string.format("校验和错误: 期望%02X, 实际%02X", calculated, checksum)
    end
    
    return true, "OK"
end

-- 解析设备地址（从数据包中提取）
local function extractDeviceAddr(data)
    -- 假设地址在第4-7字节，4字节十六进制
    if #data >= 7 then
        return string.format("%02X%02X%02X%02X", data[4], data[5], data[6], data[7])
    end
    return ""
end

-- ============================================================================
-- 核心函数：数据解析
-- ============================================================================

function AnalysisRx(deviceAddr, variables, data, dataLen)
    -- 验证数据包
    local valid, msg = validatePacket(data, dataLen)
    if not valid then
        print(string.format("[SmartSwitch] 数据包验证失败: %s", msg))
        return false
    end
    
    -- 获取命令码
    local cmd = data[3]
    
    -- 根据命令码解析数据
    if cmd == 0x01 then
        -- 状态上报
        local switch_status = data[8]
        local power = data[9] * 256 + data[10]  -- 功率（W）
        local voltage = data[11] * 256 + data[12]  -- 电压（0.1V）
        local current = data[13] * 256 + data[14]  -- 电流（mA）
        
        table.insert(variables, {
            Name = "switch_status",
            Description = "开关状态",
            Value = switch_status == 0x01 and "ON" or "OFF"
        })
        
        table.insert(variables, {
            Name = "power",
            Description = "功率",
            Value = power,
            Unit = "W"
        })
        
        table.insert(variables, {
            Name = "voltage",
            Description = "电压",
            Value = voltage / 10.0,
            Unit = "V"
        })
        
        table.insert(variables, {
            Name = "current",
            Description = "电流",
            Value = current / 1000.0,
            Unit = "A"
        })
        
        print(string.format("[SmartSwitch] 设备%s 状态上报: 开关=%s, 功率=%dW, 电压=%.1fV, 电流=%.3fA",
            deviceAddr, switch_status == 0x01 and "ON" or "OFF", power, voltage/10.0, current/1000.0))
        
        return true
        
    elseif cmd == 0x02 then
        -- 告警上报
        local alarm_type = data[8]
        local alarm_value = data[9] * 256 + data[10]
        
        local alarm_desc = ""
        if alarm_type == 0x01 then
            alarm_desc = "过流告警"
        elseif alarm_type == 0x02 then
            alarm_desc = "过压告警"
        elseif alarm_type == 0x03 then
            alarm_desc = "欠压告警"
        elseif alarm_type == 0x04 then
            alarm_desc = "过温告警"
        else
            alarm_desc = "未知告警"
        end
        
        table.insert(variables, {
            Name = "alarm_type",
            Description = "告警类型",
            Value = alarm_desc
        })
        
        table.insert(variables, {
            Name = "alarm_value",
            Description = "告警值",
            Value = alarm_value
        })
        
        print(string.format("[SmartSwitch] 设备%s 告警: %s (值=%d)", deviceAddr, alarm_desc, alarm_value))
        
        return true
        
    elseif cmd == 0x03 then
        -- 控制响应
        local result = data[8]
        
        table.insert(variables, {
            Name = "control_result",
            Description = "控制结果",
            Value = result == 0x00 and "成功" or "失败"
        })
        
        print(string.format("[SmartSwitch] 设备%s 控制响应: %s", deviceAddr, result == 0x00 and "成功" or "失败"))
        
        return true
        
    elseif cmd == 0x04 then
        -- 登录请求
        table.insert(variables, {
            Name = "frame_type",
            Description = "帧类型",
            Value = "login"
        })
        
        print(string.format("[SmartSwitch] 设备%s 登录", deviceAddr))
        
        return true
        
    elseif cmd == 0x05 then
        -- 心跳请求
        table.insert(variables, {
            Name = "frame_type",
            Description = "帧类型",
            Value = "heartbeat"
        })
        
        print(string.format("[SmartSwitch] 设备%s 心跳", deviceAddr))
        
        return true
    end
    
    print(string.format("[SmartSwitch] 未知命令码: %02X", cmd))
    return false
end

-- ============================================================================
-- 核心函数：主动上报处理
-- ============================================================================

function HandleActiveReport(deviceAddr, data, dataLen)
    local result = {
        Success = false,
        NeedResponse = false,
        Response = {},
        EventType = "data",
        DeviceData = {},
        ShouldReport = true
    }
    
    -- 验证数据包
    local valid, msg = validatePacket(data, dataLen)
    if not valid then
        print(string.format("[SmartSwitch] HandleActiveReport 数据包验证失败: %s", msg))
        return result
    end
    
    -- 获取命令码
    local cmd = data[3]
    
    if cmd == 0x01 then
        -- 状态上报
        result.EventType = "status"
        result.DeviceData.switch_status = data[8] == 0x01 and "ON" or "OFF"
        result.DeviceData.power = data[9] * 256 + data[10]
        result.DeviceData.voltage = (data[11] * 256 + data[12]) / 10.0
        result.DeviceData.current = (data[13] * 256 + data[14]) / 1000.0
        result.DeviceData.timestamp = os.time()
        
        -- 生成确认响应
        result.NeedResponse = true
        result.Response = {
            0xAA, 0x55,     -- 帧头
            0x81,           -- 响应码 (0x01 + 0x80)
            data[4], data[5], data[6], data[7],  -- 设备地址
            0x00,           -- 成功
            0x00,           -- 校验和（稍后计算）
            0x16            -- 帧尾
        }
        -- 计算校验和
        result.Response[9] = calcChecksum(result.Response, 3, 8)
        
        result.Success = true
        
        print(string.format("[SmartSwitch] 状态上报处理成功: 开关=%s, 功率=%dW",
            result.DeviceData.switch_status, result.DeviceData.power))
        
    elseif cmd == 0x02 then
        -- 告警上报
        result.EventType = "alarm"
        
        local alarm_type = data[8]
        if alarm_type == 0x01 then
            result.DeviceData.alarm = "过流告警"
        elseif alarm_type == 0x02 then
            result.DeviceData.alarm = "过压告警"
        elseif alarm_type == 0x03 then
            result.DeviceData.alarm = "欠压告警"
        elseif alarm_type == 0x04 then
            result.DeviceData.alarm = "过温告警"
        else
            result.DeviceData.alarm = "未知告警"
        end
        
        result.DeviceData.alarm_type = alarm_type
        result.DeviceData.alarm_value = data[9] * 256 + data[10]
        result.DeviceData.timestamp = os.time()
        
        -- 告警需要立即响应
        result.NeedResponse = true
        result.Response = {
            0xAA, 0x55,     -- 帧头
            0x82,           -- 响应码 (0x02 + 0x80)
            data[4], data[5], data[6], data[7],  -- 设备地址
            0x00,           -- 已收到
            0x00,           -- 校验和（稍后计算）
            0x16            -- 帧尾
        }
        result.Response[9] = calcChecksum(result.Response, 3, 8)
        
        -- 告警数据需要上报
        result.ShouldReport = true
        result.Success = true
        
        print(string.format("[SmartSwitch] 告警上报处理成功: %s (值=%d)",
            result.DeviceData.alarm, result.DeviceData.alarm_value))
        
    elseif cmd == 0x04 then
        -- 登录请求
        result.EventType = "login"
        result.DeviceData.device_type = "SmartSwitch"
        result.DeviceData.firmware_version = string.format("%d.%d", data[8], data[9])
        result.DeviceData.login_time = os.time()
        
        -- 登录响应
        result.NeedResponse = true
        result.Response = {
            0xAA, 0x55,     -- 帧头
            0x84,           -- 响应码 (0x04 + 0x80)
            data[4], data[5], data[6], data[7],  -- 设备地址
            0x00,           -- 登录成功
            0x00,           -- 校验和（稍后计算）
            0x16            -- 帧尾
        }
        result.Response[9] = calcChecksum(result.Response, 3, 8)
        
        result.ShouldReport = false  -- 登录不上报到云平台
        result.Success = true
        
        print(string.format("[SmartSwitch] 设备登录: 固件版本=%s", result.DeviceData.firmware_version))
        
    elseif cmd == 0x05 then
        -- 心跳请求
        result.EventType = "heartbeat"
        result.DeviceData.heartbeat_time = os.time()
        
        -- 心跳响应
        result.NeedResponse = true
        result.Response = {
            0xAA, 0x55,     -- 帧头
            0x85,           -- 响应码 (0x05 + 0x80)
            data[4], data[5], data[6], data[7],  -- 设备地址
            0x00,           -- 在线
            0x00,           -- 校验和（稍后计算）
            0x16            -- 帧尾
        }
        result.Response[9] = calcChecksum(result.Response, 3, 8)
        
        result.ShouldReport = false  -- 心跳不上报到云平台
        result.Success = true
        
        print(string.format("[SmartSwitch] 心跳处理成功"))
    end
    
    return result
end

-- ============================================================================
-- 核心函数：命令生成
-- ============================================================================

function DeviceCustomCmd(deviceAddr, cmdName, param, value)
    local cmd = {}
    local success = false
    
    -- 解析设备地址（假设格式：AABBCCDD）
    local addr_bytes = {}
    if #deviceAddr == 8 then
        for i = 1, 8, 2 do
            table.insert(addr_bytes, tonumber(string.sub(deviceAddr, i, i+1), 16))
        end
    else
        -- 默认地址
        addr_bytes = {0x00, 0x00, 0x00, 0x01}
    end
    
    if cmdName == "switch_on" then
        -- 开关ON命令
        cmd = {
            0xAA, 0x55,     -- 帧头
            0x03,           -- 控制命令
            addr_bytes[1], addr_bytes[2], addr_bytes[3], addr_bytes[4],  -- 设备地址
            0x01,           -- 开
            0x00,           -- 校验和（稍后计算）
            0x16            -- 帧尾
        }
        cmd[9] = calcChecksum(cmd, 3, 8)
        success = true
        
        print(string.format("[SmartSwitch] 生成开关ON命令: 设备=%s", deviceAddr))
        
    elseif cmdName == "switch_off" then
        -- 开关OFF命令
        cmd = {
            0xAA, 0x55,     -- 帧头
            0x03,           -- 控制命令
            addr_bytes[1], addr_bytes[2], addr_bytes[3], addr_bytes[4],  -- 设备地址
            0x00,           -- 关
            0x00,           -- 校验和（稍后计算）
            0x16            -- 帧尾
        }
        cmd[9] = calcChecksum(cmd, 3, 8)
        success = true
        
        print(string.format("[SmartSwitch] 生成开关OFF命令: 设备=%s", deviceAddr))
        
    elseif cmdName == "query_status" then
        -- 查询状态命令
        cmd = {
            0xAA, 0x55,     -- 帧头
            0x06,           -- 查询命令
            addr_bytes[1], addr_bytes[2], addr_bytes[3], addr_bytes[4],  -- 设备地址
            0x01,           -- 查询状态
            0x00,           -- 校验和（稍后计算）
            0x16            -- 帧尾
        }
        cmd[9] = calcChecksum(cmd, 3, 8)
        success = true
        
        print(string.format("[SmartSwitch] 生成查询状态命令: 设备=%s", deviceAddr))
        
    elseif cmdName == "set_power_threshold" then
        -- 设置功率阈值
        local threshold = tonumber(value) or 1000  -- 默认1000W
        local high = math.floor(threshold / 256)
        local low = threshold % 256
        
        cmd = {
            0xAA, 0x55,     -- 帧头
            0x07,           -- 设置命令
            addr_bytes[1], addr_bytes[2], addr_bytes[3], addr_bytes[4],  -- 设备地址
            0x01,           -- 功率阈值类型
            high, low,      -- 阈值（W）
            0x00,           -- 校验和（稍后计算）
            0x16            -- 帧尾
        }
        cmd[11] = calcChecksum(cmd, 3, 10)
        success = true
        
        print(string.format("[SmartSwitch] 生成设置功率阈值命令: 设备=%s, 阈值=%dW", deviceAddr, threshold))
        
    elseif cmdName == "login_response" then
        -- 登录响应（由网关主动生成）
        cmd = {
            0xAA, 0x55,     -- 帧头
            0x84,           -- 登录响应
            addr_bytes[1], addr_bytes[2], addr_bytes[3], addr_bytes[4],  -- 设备地址
            0x00,           -- 登录成功
            0x00,           -- 校验和（稍后计算）
            0x16            -- 帧尾
        }
        cmd[9] = calcChecksum(cmd, 3, 8)
        success = true
        
    elseif cmdName == "heartbeat_response" then
        -- 心跳响应（由网关主动生成）
        cmd = {
            0xAA, 0x55,     -- 帧头
            0x85,           -- 心跳响应
            addr_bytes[1], addr_bytes[2], addr_bytes[3], addr_bytes[4],  -- 设备地址
            0x00,           -- 在线
            0x00,           -- 校验和（稍后计算）
            0x16            -- 帧尾
        }
        cmd[9] = calcChecksum(cmd, 3, 8)
        success = true
    end
    
    return cmd, success, ""
end

-- ============================================================================
-- 打印协议信息
-- ============================================================================
print("[SmartSwitch] Lua 插件已加载: " .. protocol_name)

